package cn.ipanel.bigdata.boot.period

import cn.ipanel.bigdata.boot.date.{Day, Time}
import cn.ipanel.bigdata.utils.Dictionary

/**
 * Author: lzz
 * Date: 2022/4/2 13:53
 */
case class Period(_type: Int, _name: String) {

  def getType: Int = _type
  def getName: String = _name
  def asDate(d: Day) : Long = Period._adaptDate(d, this)
  def asTime(t: Time): Long = Period._adaptTime(t, this)
}

object Period {

  final lazy val MINUTE   : Period = Period(_type = 0x00, _name = "minute")
  final lazy val HOUR     : Period = Period(_type = 0x01, _name = "hour")
  final lazy val DAY      : Period = Period(_type = 0x02, _name = "day")
  final lazy val WEEK     : Period = Period(_type = 0x03, _name = "week")
  final lazy val MONTH    : Period = Period(_type = 0x04, _name = "month")
  final lazy val QUARTER  : Period = Period(_type = 0x05, _name = "quarter")
  final lazy val YEAR     : Period = Period(_type = 0x06, _name = "year")
  final lazy val MINUTE5  : Period = Period(_type = 0x10, _name = "minute5")
  final lazy val MINUTE10 : Period = Period(_type = 0x11, _name = "minute10")
  final lazy val MINUTE30 : Period = Period(_type = 0x12, _name = "minute30")
  final lazy val DAY7     : Period = Period(_type = 0x20, _name = "day7")
  final lazy val DAY14    : Period = Period(_type = 0x21, _name = "day14")
  final lazy val DAY30    : Period = Period(_type = 0x22, _name = "day30")
  final lazy val UNKNOWN  : Period = Period(_type = 0x99, _name = Dictionary.UNKNOWN)

  final lazy val PERIODS: Seq[Period] = {
    Seq(MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, YEAR, MINUTE5, MINUTE10, MINUTE30, DAY7, DAY14, DAY30)
  }

  private[this] final lazy val MAP: Map[String, Period] = {
    var map: Map[String, Period] = Map()
    PERIODS.foreach((p: Period) => {
      map ++= Map(p.getName -> p)
    })
    map
  }

  def as(name: String): Period = if (MAP.contains(name)) MAP(name) else UNKNOWN

  protected[Period] final def _adaptTime(time: Time, period: Period): Long = {
    period match {
      case MINUTE   => time.asMinute.toDayMinute
      case HOUR     => time.asHour.toDayHour
      case DAY      => time.asDay.toDate
      case WEEK     => time.asWeek.toDate
      case MONTH    => time.asMonth.toYearMonth
      case QUARTER  => time.asQuarter.toYearQuarter
      case YEAR     => time.asYear.toYear
      case MINUTE5  => 0L
      case MINUTE10 => 0L
      case MINUTE30 => 0L
      case DAY7     => 0L
      case DAY14    => 0L
      case DAY30    => 0L
      case _        => 0L
    }
  }

  protected[Period] final def _adaptDate(day: Day, period: Period): Long = {
    period match {
      case MINUTE   => day.toDate
      case HOUR     => day.toDate
      case DAY      => day.toDate
      case WEEK     => day.asWeek.toDate
      case MONTH    => day.toYearMonth
      case QUARTER  => day.toYearQuarter
      case YEAR     => day.toYear
      case MINUTE5  => day.toDate
      case MINUTE10 => day.toDate
      case MINUTE30 => day.toDate
      case DAY7     => day.toDate
      case DAY14    => day.toDate
      case DAY30    => day.toDate
      case _        => 0L
    }
  }
}